import 'dart:async';

import 'package:dio/dio.dart'
    show
        BaseOptions,
        Dio,
        FormData,
        LogInterceptor,
        MultipartFile,
        ProgressCallback,
        Response,
        ResponseType;
import 'package:flutter/foundation.dart';
import 'package:get/get.dart' hide Response, MultipartFile, FormData;

import '../data/sign_status.dart';


class NetworkRequestManager {
  SignStatusManager signStatusManager = Get.find<SignStatusManager>();

  Future<Response> signApk(String url, String? apkPath, String signTypeName,
      List<int>? bytes) async {
    final Dio dio = Dio(BaseOptions(responseType: ResponseType.bytes));
    dio.interceptors.add(LogInterceptor(responseBody: false));
    Map<String, dynamic> map = {
      'key_type': signTypeName,
      'key_name': 'platform'
    };
    if (apkPath != null) {
      map["file"] = await MultipartFile.fromFile(apkPath);
    }
    if (bytes != null && bytes.isNotEmpty) {
      map["file"] = MultipartFile.fromBytes(bytes);
    }
    FormData formData = FormData.fromMap(map);
    if (kDebugMode) {
      print("filepath:$apkPath");
    }
    signStatusManager.updateStatus(SignStatus.startUpload);
    Response response = await dio
        .post(url, data: formData, onSendProgress: (int sent, int total) {
          if (kDebugMode) {
            print('onSend $sent $total');
            if (sent < total) {
              signStatusManager.updateStatus(SignStatus.uploading);
            } else {
              signStatusManager.updateStatus(SignStatus.uploaded);
              Timer(const Duration(milliseconds: 100), () {
                signStatusManager.updateStatus(SignStatus.startSign);
              });
            }
          }
        }, onReceiveProgress: (int sent, int total) {
          if (kDebugMode) {
            print('onReceive $sent $total');
          }
        })
        .timeout(const Duration(minutes: 1))
        .catchError((err) {
          print('Error: $err'); // Prints 401.
        }, test: (error) {
          return error is int && error >= 400;
        });
    if (response.statusCode == 200) {
      signStatusManager.updateStatus(SignStatus.signSuccess);
    } else {
      signStatusManager.updateStatus(SignStatus.signFail);
    }
    return Future.value(response);
  }

  Future<Response> signApkWithCallback(
      String url,
      String apkPath,
      String signTypeName,
      ProgressCallback sendProgress,
      ProgressCallback receiverCallBack) async {
    final Dio dio = Dio(BaseOptions(responseType: ResponseType.bytes));
    dio.interceptors.add(LogInterceptor(responseBody: false));
    Map<String, dynamic> map = {
      'key_type': signTypeName,
      'key_name': 'platform'
    };
    map["file"] = await MultipartFile.fromFile(apkPath);
    FormData formData = FormData.fromMap(map);
    if (kDebugMode) {
      print("filepath:$apkPath");
    }
    signStatusManager.updateStatus(SignStatus.startUpload);
    Response response = await dio
        .post(url, data: formData, onSendProgress: (int sent, int total) {
          if (kDebugMode) {
            print('onSend $sent $total');
          }
          sendProgress.call(sent, total);

          //   if (sent < total) {
          //     signStatusManager.updateStatus(SignStatus.uploading);
          //   } else {
          //     signStatusManager.updateStatus(SignStatus.uploaded);
          //     Timer(const Duration(milliseconds: 100), () {
          //       signStatusManager.updateStatus(SignStatus.startSign);
          //     });
          //   }
          // }
        }, onReceiveProgress: (int sent, int total) {
          if (kDebugMode) {
            print('onReceive $sent $total');
          }
          receiverCallBack.call(sent, total);
        })
        .timeout(const Duration(minutes: 1))
        .catchError((err) {
          print('Error: $err'); // Prints 401.
        }, test: (error) {
          return error is int && error >= 400;
        });
    if (response.statusCode == 200) {
      signStatusManager.updateStatus(SignStatus.signSuccess);
    } else {
      signStatusManager.updateStatus(SignStatus.signFail);
    }
    return Future.value(response);
  }
}
